//
// Created by TongHua on 2020/12/30.
//

#ifndef WEBSERVER_LOGGER_H
#define WEBSERVER_LOGGER_H

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "../Utils/BlockQueue.h"
#include "../Logger/Logger.h"

using std::string;

class Logger {
public:
    static Logger* Instance()
    {
        static Logger _instance;
        return &_instance;
    }
    static void* FlushLogThread(void* _arg)
    {
        Logger::Instance()->AsyncWriteLog();
    }

    bool Init( const char* _filename, int _log_buf_size = 8192, int _split_lines = 5000000, int _max_queue_size = 0 );

    void WriteLog( int _level, const char* format, ... );

    void Flush();

private:
    Logger();

    virtual ~Logger();

    /**
     * 异步写入消息
     * @return
     */
    void* AsyncWriteLog()
    {
        string single_log;
        while ( m_log_queue->Pop( single_log ) )
        {
            m_mutex.Lock();
            fputs( single_log.c_str(), m_fp );
            m_mutex.UnLock();
        }
    }

private:
    Locker m_mutex;                                 // 互斥锁
    BlockQueue< string > *m_log_queue;              // 阻塞队列
    FILE* m_fp;                                     // 文件指针
    char m_dir_name[128];                           // 路径
    char m_log_name[128];                           // 文件名
    int m_split_lines;                              // 最大行数
    int m_log_buf_size;                             // 日志缓冲区大小
    long long m_count;                              // 行数记录
    int m_today;                                    // 日期
    char* m_buf;                                    // 缓冲区
    bool m_is_async;                                // 是否同步
};

#define LOG_DEBUG(format, ...)  Logger::Instance()->WriteLog(0, format, ##__VA_ARGS__)
#define LOG_INFO(format, ...)   Logger::Instance()->WriteLog(1, format, ##__VA_ARGS__)
#define LOG_WARN(format, ...)   Logger::Instance()->WriteLog(2, format, ##__VA_ARGS__)
#define LOG_ERROR(format, ...)  Logger::Instance()->WriteLog(3, format, ##__VA_ARGS__)

#endif //WEBSERVER_LOGGER_H
